﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ZenHR.AttData.Collection.LinkDBHelper
{
    class AnalyzeStrHelper
    {
        public static Dictionary<int, string> AnalyzeStr(string code)
        {
            string s = code;
            Dictionary<int, string> allresult = new Dictionary<int, string>();
            List<string> temp = new List<string>();
            string strtmp = "";
            strtmp = s[0].ToString();
            temp.Add(strtmp);
            for (int i = 1; i < s.Length; i++)
            {
                if (s[i].ToString() == strtmp)
                {
                    temp.Add(s[i].ToString());
                }
                else
                {
                    strtmp = s[i].ToString();
                    string result = String.Join("", temp);
                    allresult.Add(i - result.Length + 1, result);
                    temp.Clear();
                    temp.Add(strtmp);
                }
            }
            if (temp.Count > 0)
            {
                string result = String.Join("", temp);
                allresult.Add(s.Length - result.Length + 1, result);
                temp.Clear();
            }
            return allresult;
        }

        /// <summary>
        /// 解析文本转datatable
        /// </summary>
        /// <param name="str_format"></param>
        /// <param name="str_path"></param>
        /// <returns></returns>
        public static DataTable ExecuteDataTable(string str_format, string str_path,string ignore="",int current_index=-1,string _Suffix="")
        {
            DataTable tblDatas = new DataTable("Datas");
            tblDatas.Columns.Add("index_id", Type.GetType("System.String"));
            tblDatas.Columns.Add("emp_code", Type.GetType("System.String"));
            tblDatas.Columns.Add("card_number", Type.GetType("System.String"));
            tblDatas.Columns.Add("check_time", Type.GetType("System.String"));
            tblDatas.Columns.Add("inorout", Type.GetType("System.String"));
            tblDatas.Columns.Add("extend_info", Type.GetType("System.String"));

            DirectoryInfo TheFolder = new DirectoryInfo(str_path);

            //遍历文件
            foreach (FileInfo NextFile in TheFolder.GetFiles())
            {

                DateTime now = DateTime.Now;
                //大于今天的文件才会被采集
                if (NextFile.LastWriteTime > new DateTime(now.Year, now.Month, now.Day).AddDays(-1))
                {
                    if (NextFile.Name != ignore)
                    {
                        //如果有配置后缀检测，判断后缀不同不处理文件
                        if (_Suffix != "" && NextFile.Extension != "."+_Suffix)
                        {
                                //不处理；
                        }
                        else
                        {
                            foreach (string str in System.IO.File.ReadAllLines(NextFile.FullName, Encoding.Default))
                            {
                                try
                                {
                                    string file_format = str_format;
                                    int? cardno_startpoint = null,
                                        cardno_endpoint = null,
                                        year_startpoint = null,
                                        year_endpoint = null,
                                        month_startpoint = null,
                                        month_endpoint = null,
                                        day_startpoint = null,
                                        day_endpoint = null,
                                        hour_startpoint = null,
                                        hour_endpoint = null,
                                        minute_startpoint = null,
                                        minute_endpoint = null,
                                        second_startpoint = null,
                                        second_endpoint = null,
                                        location_startpoint = null,
                                        location_endpoint = null,
                                        empcode_startpoint = null,
                                        empcode_endpoint = null
                                        ;

                                    Dictionary<int, string> allresult = AnalyzeStrHelper.AnalyzeStr(file_format);
                                    var queryPoint = from p in allresult where p.Value.Contains("C") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        cardno_startpoint = queryPoint.First().Key;
                                        cardno_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }
                                    queryPoint = from p in allresult where p.Value.Contains("Y") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        year_startpoint = queryPoint.First().Key;
                                        year_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }
                                    queryPoint = from p in allresult where p.Value.Contains("M") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        month_startpoint = queryPoint.First().Key;
                                        month_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }
                                    queryPoint = from p in allresult where p.Value.Contains("D") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        day_startpoint = queryPoint.First().Key;
                                        day_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }
                                    queryPoint = from p in allresult where p.Value.Contains("H") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        hour_startpoint = queryPoint.First().Key;
                                        hour_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }
                                    queryPoint = from p in allresult where p.Value.Contains("N") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        minute_startpoint = queryPoint.First().Key;
                                        minute_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }
                                    queryPoint = from p in allresult where p.Value.Contains("S") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        second_startpoint = queryPoint.First().Key;
                                        second_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }
                                    queryPoint = from p in allresult where p.Value.Contains("L") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        location_startpoint = queryPoint.First().Key;
                                        location_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }

                                    queryPoint = from p in allresult where p.Value.Contains("E") select p;
                                    if (queryPoint.Count() > 0)
                                    {
                                        empcode_startpoint = queryPoint.First().Key;
                                        empcode_endpoint = queryPoint.First().Value.Length + queryPoint.First().Key - 1;
                                    }

                                    var _y = str.Substring(year_startpoint.Value - 1, year_endpoint.Value + 1 - year_startpoint.Value);
                                    var _m = str.Substring(month_startpoint.Value - 1, month_endpoint.Value + 1 - month_startpoint.Value);
                                    var _d = str.Substring(day_startpoint.Value - 1, day_endpoint.Value + 1 - day_startpoint.Value);
                                    var _h = str.Substring(hour_startpoint.Value - 1, hour_endpoint.Value + 1 - hour_startpoint.Value);
                                    var _n = str.Substring(minute_startpoint.Value - 1, minute_endpoint.Value + 1 - minute_startpoint.Value);

                                    if (_y.Length == 2)
                                    {
                                        _y = "20" + _y;
                                    }

                                    var _emp_code = empcode_startpoint is null ? "" : str.Substring(empcode_startpoint.Value - 1, empcode_endpoint.Value + 1 - empcode_startpoint.Value);
                                    var _card_number = cardno_startpoint is null ? "" : str.Substring(cardno_startpoint.Value - 1, cardno_endpoint.Value + 1 - cardno_startpoint.Value);
                                    var _check_time = _y + "-" + _m + "-" + _d + " " + _h + ":" + _n;
                                    var _inorout = "";
                                    var _extend_info = "";

                                    //判断卡考是否补0 (根据负值多少判断)
                                    if (current_index < -1)
                                    {
                                        switch (current_index)
                                        {
                                            case -2:
                                                _card_number = "00" + _card_number;
                                                break;
                                            case -3:
                                                _card_number = "000" + _card_number;
                                                break;
                                            case -4:
                                                _card_number = "0000" + _card_number;
                                                break;
                                            case -5:
                                                _card_number = "00000" + _card_number;
                                                break;
                                            case -6:
                                                _card_number = "000000" + _card_number;
                                                break;
                                            case -7:
                                                _card_number = "0000000" + _card_number;
                                                break;
                                            case -8:
                                                _card_number = "00000000" + _card_number;
                                                break;
                                        }
                                    }

                                    tblDatas.Rows.Add(new object[] { "0", _emp_code, _card_number, _check_time, _inorout, _extend_info });

                                }
                                catch (Exception)
                                {

                                }


                            }

                        }
                      
                    }
                   
                }

                
            }
        
            return tblDatas;

        }

        /// <summary>
        /// 共享文件读取帮助类
        /// </summary>
        public class SharedTool : IDisposable
        {
            // obtains user token       
            [DllImport("advapi32.dll", SetLastError = true)]
            static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
                int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

            // closes open handes returned by LogonUser       
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            extern static bool CloseHandle(IntPtr handle);

            [DllImport("Advapi32.DLL")]
            static extern bool ImpersonateLoggedOnUser(IntPtr hToken);

            [DllImport("Advapi32.DLL")]
            static extern bool RevertToSelf();
            const int LOGON32_PROVIDER_DEFAULT = 0;
            const int LOGON32_LOGON_NEWCREDENTIALS = 9;//域控中的需要用:Interactive = 2       
            private bool disposed;

            public SharedTool(string username, string password, string ip)
            {
                // initialize tokens       
                IntPtr pExistingTokenHandle = new IntPtr(0);
                IntPtr pDuplicateTokenHandle = new IntPtr(0);

                try
                {
                    // get handle to token       
                    bool bImpersonated = LogonUser(username, ip, password,
                        LOGON32_LOGON_NEWCREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);

                    if (bImpersonated)
                    {
                        if (!ImpersonateLoggedOnUser(pExistingTokenHandle))
                        {
                            int nErrorCode = Marshal.GetLastWin32Error();
                            throw new Exception("ImpersonateLoggedOnUser error;Code=" + nErrorCode);
                        }
                    }
                    else
                    {
                        int nErrorCode = Marshal.GetLastWin32Error();
                        throw new Exception("LogonUser error;Code=" + nErrorCode);
                    }
                }
                finally
                {
                    // close handle(s)       
                    if (pExistingTokenHandle != IntPtr.Zero)
                        CloseHandle(pExistingTokenHandle);
                    if (pDuplicateTokenHandle != IntPtr.Zero)
                        CloseHandle(pDuplicateTokenHandle);
                }
            }

            protected virtual void Dispose(bool disposing)
            {
                if (!disposed)
                {
                    RevertToSelf();
                    disposed = true;
                }
            }

            public void Dispose()
            {
                Dispose(true);
            }
        }

    }
}
